import { install } from 'source-map-support';
install();

import dotenv from 'dotenv';
import fs from 'fs-extra';
import path from 'path';
import program from 'commander';
import { BuildManager } from './BuildManager.js';
import { CmdOption } from './CmdOption.js';
import { fileURLToPath } from 'url';
import { toolchain } from './toolchain.js';
import { unlockWorkspace } from './tools/lock.js';
import { sendBuildFailureAlert } from './tools/alert.js';
import { env, fillEnvValues } from './env.js';
import { handleRemote } from './tools/secretary.js';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
toolchain.__dirname = __dirname;
const myPackage = await fs.readJSON(path.join(__dirname, '../package.json'));


const rmQuotes = (val: string): string => {
    let rst = val.match(/(['"])(.*)\1/);
    if(rst) return rst[2];

    return val;
}

program
	.version(myPackage.version, "-v, --version")
	.option("-n, --project-name <string>", "[MUST] project name.", rmQuotes)
	.option("-i, --game-ids <string>", "[MUST] game ids seperated by comma.", rmQuotes)
	.option("-t, --old-tools-root <string>", "[MUST] old tools root.", rmQuotes)
	.option("-e, --build-exe", "build exe file or not.")
	.option("--webgl-compress-tex", "Compress texture or not, webgl only.")
	.option("-p, --platform <string>", "[MUST] platform name.", rmQuotes)
	.option("--project-root <string>", "工程目录，可选，如未指定，则根据一定规则推断。使用本参数将便利本地构建。", rmQuotes)
	.option("--engine <string>", "engine, unity/laya/flash, unity as default.", rmQuotes, 'unity')
	.option("--webgl-runtime <string>", "webgl runtime, all/browser/minigame.", rmQuotes)
	.option("-u, --upload-res", "upload res files or not.")
	.option("--set-min-app", "set as min app version.")
	.option("--upload-minigame-desc <string>", "description for uploading minigame.")
	.option("--minigame-enable-debug-log", "查看资源日志是否有读取缓存.")
	.option("--minigame-show-time-log-modal", "显示timelog开发者可以看到小游戏目前的启动首屏时长.")
	.option("--minigame-enable-profile-stats", "打开性能面板.")
	.option("--task <string>", "Build task.", rmQuotes)
	.option("--task-parameter <string>", "Build task parameter.", rmQuotes)
	.option("--skip <string>", "Skip tasks, seperated by comma, SVNOperationTask|WebGLBuildMiniGameTask|WebGLCompressTextureTask etc.")
	.option("--execute <string>", "Execute specified tasks, seperated by comma, SVNOperationTask|WebGLBuildMiniGameTask|WebGLCompressTextureTask etc.")
	.option("--execute-tpl <string>", "built-in execute tasks template, OnlyTs|OnlyJson etc.")
	.option("--short-output", "output shorten logs.")
	.option("-d, --debug", "Debug mode.")
	.option("--isTiShen", "Is tishen.")
	.option("--check-i18n <string>", "Check i18n error or not.")
	.option("--report <string>", "Report level, seperated by comma, JsonDiff etc. Default: none, and JsonDiff if publish.")
	.option("--rebuild <string>", "Rebuild, all input options are as same as the specified history build.", rmQuotes)
    .parse(process.argv);

let opts = program.opts() as CmdOption;

// 必须使用.env保存svn账号等信息，禁止在脚本中明文书写账号信息
// 请在hudson后台配置环境变量UNITY_BUILDER_ENV指定.env文件地址
const envFile = process.env.UNITY_BUILDER_ENV || path.join(toolchain.__dirname, '../.env');
if (fs.existsSync(envFile)) {
	dotenv.config({ path: envFile });
	fillEnvValues(path.dirname(envFile));
	if (!env.svnUser || !env.svnPswd) {
		console.error('should specify svn account info in .env file!');
		process.exit(1);
	}
	toolchain.svnClient.setConfig({
		username: env.svnUser,
		password: env.svnPswd
	});
} else {
	console.error('no env file');
	process.exit(1);
}

if (opts.execute) opts.executeTpl = undefined;
// 如果是rebuild模式，则先处理rebuild参数，之所以叫rebuild参数是历史原因，更确切的应该叫remote参数
// ~是为了兼容拉分支task的传参
if (opts.rebuild && opts.rebuild != '~') {
	console.log(`remote mode, handle remote parameters: ${opts.rebuild}`);
	const res = await handleRemote(opts.rebuild);
	if (res.code != 0) {
		console.error('handle remote parameter failed:', res);
		process.exit(1);
	}
	if (res.option) opts = res.option;
}
console.log(`cmd options: ${JSON.stringify(opts)}`);
toolchain.option = opts;

const worker = new BuildManager(opts);
process.on('SIGKILL', async () => {
	console.log('on SIGKILL');
	// 普通exit会自动释放构建锁
	await unlockWorkspace();
});

worker.start().catch(async (reason)=>{
	console.error('[ERROR]Error encountered!');
	if (reason instanceof Error) {
		await sendBuildFailureAlert(reason.message);
		console.error(reason.stack);
	} else if (typeof(reason) == 'string') {
		await sendBuildFailureAlert(reason);
	} else {
		await sendBuildFailureAlert('原因详见日志');
	}
	process.exit(1);
});
